﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Linq.Expressions;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading;
using System.Threading.Tasks;

namespace DogJson
{

    public class TClassA
    {
        public static void Fool(int a, string b) 
        {

        }
        public static void Foo2(int a, string b)
        {

        }

    }
    public class Program
    {

        private unsafe JsonValue GCC(void* a)
        {
            return *(JsonValue*)a;
        }


        /// <summary>
        /// 对多维数组的每个元素赋相同的值
        /// </summary>
        /// <param name="arrayObject"></param>
        /// <param name="value"></param>
        static void SetArrayValue(object arrayObject, object value)
        {
            Array array = arrayObject as Array;

            int rank = array.Rank;
            int[] lengths = new int[rank];
            for (int i = 0; i < rank; i++)
            {
                lengths[i] = array.GetLength(i);
            }
            int nowRank = 0;
            int[] indices = new int[rank];

            do
            {
                for (int i = 0; i < lengths[0]; i++)
                {
                    indices[0] = i;
                    array.SetValue(13123, indices);
                }
                nowRank = 1;
            Chake:
                ++indices[nowRank];
                if (indices[nowRank] == lengths[nowRank])
                {
                    ++nowRank;
                    if (nowRank < rank)
                    {
                        goto Chake;
                    }
                    else
                    {
                        break;
                    }
                }
                for (int i = 0; i < nowRank; i++)
                {
                    indices[i] = 0;
                }
            } while (true);
        }

        /// <summary>
        /// 多维数组按照 [index,index,,,] : Value输出
        /// </summary>
        /// <param name="array"></param>
        /// <returns></returns>
        static string ArrayToString(Array array)
        {
            StringBuilder sb = new StringBuilder();
            int rank = array.Rank;
            int[] lengths = new int[rank];
            for (int i = 0; i < rank; i++)
            {
                lengths[i] = array.GetLength(i);
            }
            int nowRank = 0;
            int[] indices = new int[rank];

            do
            {
                for (int i = 0; i < lengths[0]; i++)
                {
                    indices[0] = i;
                    sb.Append("[");
                    for (int j = 0; j < rank - 1; j++)
                    {
                        sb.Append(indices[j] + ",");
                    }
                    sb.Append(indices[rank - 1] + "] : ");
                    sb.AppendLine(array.GetValue(indices).ToString());
                }
                nowRank = 1;
            Chake:
                ++indices[nowRank];
                if (indices[nowRank] == lengths[nowRank])
                {
                    ++nowRank;
                    if (nowRank < rank)
                    {
                        goto Chake;
                    }
                    else
                    {
                        return sb.ToString();
                    }
                }
                for (int i = 0; i < nowRank; i++)
                {
                    indices[i] = 0;
                }
            } while (true);
        }

        /// <summary>
        /// 多维数组按照 Json 格式输出
        /// </summary>
        /// <param name="array"></param>
        /// <returns></returns>
        static string ArrayToJsonString(Array array)
        {
            StringBuilder sb = new StringBuilder();
            int rank = array.Rank;
            int[] lengths = new int[rank];
            for (int i = 0; i < rank; i++)
            {
                lengths[i] = array.GetLength(i);
            }
            for (int i = 0; i < rank - 1; i++)
            {
                for (int j = 0; j < i; j++)
                {
                    sb.Append(" ");//\t
                }
                sb.AppendLine("[");
            }
            int nowRank = 0;
            int[] indices = new int[rank];

            do
            {
                for (int j = 0; j < rank; j++)
                {
                    sb.Append(" ");//\t
                }
                sb.Append("[");
                for (int i = 0; i < lengths[0]; i++)
                {
                    indices[0] = i;
                    if (i < lengths[0] - 1)
                    {
                        sb.Append(array.GetValue(indices).ToString() + ",");
                    }
                    else
                    {
                        sb.Append(array.GetValue(indices).ToString());
                    }
                }
                sb.Append("]");
                nowRank = 1;
            Chake:
                ++indices[nowRank];
                if (indices[nowRank] == lengths[nowRank])
                {
                    sb.AppendLine();
                    ++nowRank;
                    if (nowRank < rank)
                    {
                        for (int j = 0; j < rank - nowRank + 1; j++)
                        {
                            sb.Append(" ");//\t
                        }
                        sb.Append("]");
                        goto Chake;
                    }
                    else
                    {
                        sb.AppendLine("]");
                        return sb.ToString();
                    }
                }
                else
                {
                    sb.AppendLine(",");
                }
                for (int i = 0; i < nowRank; i++)
                {
                    indices[i] = 0;
                }
                for (int i = 0; i < nowRank - 1; i++)
                {
                    for (int j = 0; j < rank - i; j++)
                    {
                        sb.Append(" ");//\t
                    }
                    sb.AppendLine("[");
                }
            } while (true);
        }


        static int testCount = 1000000;

        const int testCount2 = 97;
        const int testCount3 = 8;
        static int overBit = -0;

        static int[] bsdad = new int[testCount2 * testCount3];

        static bool[] Run = new bool[testCount3];
        static int[] RunIndex = new int[testCount3];

        static void TestCall(int j, int value)
        {
            for (int i = 0; i < 300; i++)
            {
                bsdad[j] = value;
            }
        }

        static int over = 0;
        static object lockall = new object();

        static void Main99(string[] args)
        {
            Stopwatch oTime = new Stopwatch();

            oTime.Reset(); oTime.Start();
            for (int i = 0; i < testCount; i++)
            {
                for (int j = 0; j < bsdad.Length; j++)
                {
                    TestCall(j, 999);
                }
            }
            oTime.Stop();
            Console.WriteLine("for：{0} 毫秒", oTime.Elapsed.TotalMilliseconds);

            Thread[] threads = new Thread[testCount3];
            overBit = 0;
            over = 0;

            for (int i = 0; i < testCount3; i++)
            {
                overBit |= 1 << i;
                threads[i] = new Thread(new ParameterizedThreadStart(Thread1));
            }
            for (int i = 0; i < testCount3; i++)
            {
                threads[i].Start(i);
            }
            //Thread.Sleep(1000);
            oTime.Reset(); oTime.Start();

            for (int j = 0; j < testCount; j++)
            {
                over = overBit;
                //for (int i = 0; i < testCount3; i++)
                //{
                //    Run[i] = true;
                //}

                while (over != 0)
                {

                }
                //Console.WriteLine("ZZZ ");
                //Etd:
                //for (int i = 0; i < testCount3; i++)
                //{
                //    if (Run[i])
                //    {
                //        goto Etd;
                //    }
                //}
            }

            oTime.Stop();
            Console.WriteLine("Thread1：{0} 毫秒", oTime.Elapsed.TotalMilliseconds);

            //oTime.Reset(); oTime.Start();
            //for (int i = 0; i < testCount; i++)
            //{
            //    //while (true)
            //    {
            //        Parallel.For(0, bsdad.Length, d =>
            //        {
            //            bsdad[d] = 999;
            //        });

            //        //        ParallelLoopResult result = Parallel.ForEach<int>(bsdad, d =>
            //        //{
            //        //    bsdad[d] = 999;
            //        //});
            //        //if (result.IsCompleted)
            //        //{
            //        //    break;
            //        //}
            //    }
            //    //Console.WriteLine("是否完成:{0}", result.IsCompleted);
            //}
            //oTime.Stop();
            //Console.WriteLine("Thread1：{0} 毫秒", oTime.Elapsed.TotalMilliseconds);


            Console.ReadKey();
        }


        /// <summary>
        /// 创建有参的方法
        /// 注意：方法里面的参数类型必须是Object类型
        /// </summary>
        /// <param name="obj"></param>
        static void Thread1(object obj)
        {
            //Tuple<Thread, int> t = (System.Tuple<Thread, int>)obj;
            
            //int d = t.Item2;
            //Thread thread = t.Item1;

            int d = (int)obj;


            int max = d * testCount2 + testCount2;
            while (true)
            {
                while ((over & (1 << d)) == 0)
                {

                }
                for (int i = d * testCount2; i < max; i++)
                {
                    TestCall(i, 9999);
                }
                //Console.WriteLine("XX " + d);
                over &= (~(1 << d));
                //Run[d] = false;
                //--over;
            }
            //while (true)
            //{
            //    for (int i = d, max = d + testCount2; i < max; i++)
            //    {
            //        bsdad[i] = 999;
            //    }

            //    over--;
            //    return;
            //    thread.Suspend();
            //}
        }

        static void Threadd0(object obj)
        {
            Tuple<Thread, int> t = (System.Tuple<Thread, int>)obj;

            int d = t.Item2;
            Thread thread = t.Item1;
            int max = bsdad.Length;// d * testCount2 + testCount2;
            while (true)
            {
                while ((over & (1 << d)) == 0)
                {

                }
                for (int i = 0; i < max; i++)
                {
                    RunIndex[1] = 0;
                    if (RunIndex[1] == i)
                    {
                        break;
                    }
                    bsdad[i] = 9999;
                }
                //Console.WriteLine("XX " + d);
                over &= (~(1 << d));
                //Run[d] = false;
                //--over;
            }
        }


        static T Read<T>(IntPtr address)
        {
            var obj = default(T);
            var tr = __makeref(obj);

            //This is equivalent to shooting yourself in the foot
            //but it's the only high-perf solution in some cases
            //it sets the first field of the TypedReference (which is a pointer)
            //to the address you give it, then it dereferences the value.
            //Better be 10000% sure that your type T is unmanaged/blittable...
            unsafe { *(IntPtr*)(&tr) = address; }

            return __refvalue(tr, T);
        }

        unsafe struct SpanString 
        {
            public char* txt;
            public int startIndex;
            public int length;
            public SpanString(char* txt, int startIndex, int length)
            {
                this.txt = txt;
                this.startIndex = startIndex;
                this.length = length;
            }
        }

        [StructLayout(LayoutKind.Sequential)]
        internal sealed class Pinnable<T>
        {
            public T Data;
        }
        private static IntPtr MeasureArrayAdjustment<T>()
        {
            T[] array = new T[2];
            return Unsafe.ByteOffset(ref Unsafe.As<Pinnable<T>>(array).Data, ref array[1]);
        }

        private static unsafe ref T GetPinnableReference<T>(Pinnable<T> _pinnable, IntPtr _byteOffset)
        {
            return ref Unsafe.AddByteOffset(ref _pinnable.Data, _byteOffset);
        }
        public class ReflectionManage
        {
            class A
            {
                private int k1;
                protected int b4;
            }
            class B : A
            {
                private int k2;
                protected new int b3;
            }

            class C : B
            {
                private int Is64BitProcess;
                private int Is64BitProcess_2;
                private int Is64BitProcess_3;
                protected new int b;
            }

            unsafe static void M2ain(string[] args)
            {
                FieldInfo[] vs = GetTypeFields(typeof(C));

                //List<int> os1s = new List<int>();
                Type typ = typeof(C);
                //foreach (var nf in vs)
                //{
                //    var handle = nf.FieldHandle;
                //    int os1 = UnsafeOperation.GetFeildOffset(handle.Value);
                //    os1s.Add(os1);
                //}


                TypeReflectionWarp typeReflectionWarp = GetDictionaryTypeFields(typ);
                typeReflectionWarp.End();

                int testCount = 1000000;
                Stopwatch oTime = new Stopwatch();
                oTime.Reset(); oTime.Start();
                for (int i = 0; i < testCount; i++)
                {
                    var v = new TypeField(typ.GetField("Is64BitProcess",
                            BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public));
                }
                oTime.Stop();
                Console.WriteLine("ReadJsonText：{0} 毫秒", oTime.Elapsed.TotalMilliseconds);

                string strjson = "0123456Is64BitProcess6456546546465464";

                string Is64BitProcess = "Is64BitProcess";

                fixed (char* cp = strjson)
                {
                    //char* ck = cp + 7;

                    int length = Is64BitProcess.Length;

                    oTime.Reset(); oTime.Start();
                    for (int i = 0; i < testCount; i++)
                    {
                        var v = typeReflectionWarp.nameOfField[new string(cp, 7, length)].fieldInfo;
                    }
                    oTime.Stop();
                    Console.WriteLine("ReadJsonText：{0} 毫秒", oTime.Elapsed.TotalMilliseconds);

                    oTime.Reset(); oTime.Start();
                    for (int i = 0; i < testCount; i++)
                    {
                        var v = typeReflectionWarp.GetTypeField2(cp + 7, length).fieldInfo;
                    }
                    oTime.Stop();
                    Console.WriteLine("ReadJsonText：{0} 毫秒", oTime.Elapsed.TotalMilliseconds);

                    oTime.Reset(); oTime.Start();
                    for (int i = 0; i < testCount; i++)
                    {
                        var v = typeReflectionWarp.GetTypeField(cp + 7, length).fieldInfo;
                    }
                    oTime.Stop();
                    Console.WriteLine("ReadJsonText：{0} 毫秒", oTime.Elapsed.TotalMilliseconds);
                }


                Console.Read();
            }


            public static TypeReflectionWarp GetDictionaryTypeFields(Type type)
            {
                TypeReflectionWarp typeReflectionWarp = new TypeReflectionWarp();
                FieldInfo[] typeFieldsNow = type.GetFields(BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public);
                foreach (var item in typeFieldsNow)
                {
                    if (typeReflectionWarp.nameOfField.ContainsKey(item.Name))
                    {
                        typeReflectionWarp.nameOfField[item.Name] = new TypeField(type.GetField(item.Name,
                            BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public));
                    }
                    else
                    {
                        typeReflectionWarp.nameOfField[item.Name] = new TypeField(item);
                    }
                }

                while (type.BaseType != typeof(object))
                {
                    foreach (var item in type.BaseType.GetFields(BindingFlags.Instance | BindingFlags.NonPublic))
                    {
                        if (item.Attributes == FieldAttributes.Private)
                        {
                            if (!typeReflectionWarp.nameOfField.ContainsKey(item.Name))
                            {
                                typeReflectionWarp.nameOfField[item.Name] = new TypeField(item);
                            }
                        }
                    }
                    type = type.BaseType;
                }
                return typeReflectionWarp;
            }



            public static FieldInfo[] GetTypeFields(Type type)
            {
                FieldInfo[] typeFieldsNow = type.GetFields(BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public);
                List<FieldInfo> list = new List<FieldInfo>(typeFieldsNow);
                while (type.BaseType != typeof(object))
                {
                    foreach (var item in type.BaseType.GetFields(BindingFlags.Instance | BindingFlags.NonPublic))
                    {
                        if (item.Attributes == FieldAttributes.Private)
                        {
                            list.Add(item);
                        }
                    }
                    type = type.BaseType;
                }
                return list.ToArray();
            }


            public unsafe class TypeReflectionWarp
            {
                public Dictionary<string, TypeField> nameOfField = new Dictionary<string, TypeField>();

                Dictionary<int, TypeField> charNameOfField2 = new Dictionary<int, TypeField>();


                public void End()
                {
                    foreach (var item in nameOfField)
                    {
                        charNameOfField2[item.Key.Length] = item.Value;
                    }

                    Dictionary<int, List<Tuple<string, TypeField>>> pairs = new Dictionary<int, List<Tuple<string, TypeField>>>();

                    foreach (var item in nameOfField)
                    {
                        var v = charNameOfField[item.Key.Length] = new SelectName(0);
                        if (!pairs.ContainsKey(item.Key.Length))
                        {
                            pairs[item.Key.Length] = new List<Tuple<string, TypeField>>();
                        }
                        pairs[item.Key.Length].Add(new Tuple<string, TypeField>(item.Key, item.Value));

                    }
                    foreach (var item in pairs)
                    {
                        List<Tuple<List<long>, TypeField>> all = new List<Tuple<List<long>, TypeField>>();
                        var v = charNameOfField[item.Key] = new SelectName(0);
                        foreach (Tuple<string, TypeField> item2 in item.Value)
                        {
                            all.Add(new Tuple<List<long>, TypeField>(StringToLong(item2.Item1), item2.Item2));
                        }
                        if (all.Count == 1)
                        {
                            charNameOfField[item.Key] = new SelectName(all[0].Item2, all[0].Item1[0]);
                        }
                        else 
                        { 
                            End2(all, item.Key, v);
                        }
                    }

                    int d = 0;
                }


                public List<long> StringToLong(string str)
                {
                    List<long> vs = new List<long>();
                    int length = str.Length;
                    fixed (char* mm = str)
                    {
                        long* lp = (long*)mm;
                        for (int i = 0; i < length / 4; i++)
                        {
                            long l = *lp;
                            vs.Add(l);
                            ++lp;
                        }
                        long over = 0;
                        for (int i = length / 4 * 4; i < length; i++)
                        {
                            over |= ((long)(*(mm + i))) << (i * 2);
                        }
                        if (over != 0)
                        {
                            vs.Add(over);
                        }
                    }
                    return vs;
                }


                private void End2(List<Tuple<List<long>, TypeField>> all, int size, SelectName parent)
                {
                    Dictionary<long, List<Tuple<List<long>, TypeField>>> kd = new Dictionary<long, List<Tuple<List<long>, TypeField>>>();

                    foreach (var item in all)
                    {
                        if (kd.ContainsKey(item.Item1[0]))
                        {
                            kd[item.Item1[0]].Add(item);
                        }
                        else
                        {
                            (kd[item.Item1[0]] = new List<Tuple<List<long>, TypeField>>()).Add(item);
                        }
                    }

                    foreach (var item in kd.Values)
                    {
                        if (item.Count == 1)
                        {
                            long k = item[0].Item1[0];
                            parent.select[k] = new SelectName(item[0].Item2, k);
                        }
                        else
                        {
                            long k = item[0].Item1[0];
                            int count = 0;
                            foreach (Tuple<List<long>, TypeField> item2 in item)
                            {
                                item2.Item1.RemoveAt(0);
                                count = item2.Item1.Count;
                            }
                            if (count > 0)
                            {
                                parent.select[k] = new SelectName(k);
                                End2(item, count, parent.select[k]);
                            }
                            else
                            {

                            }
                        }
                    }


                }



                public unsafe TypeField GetTypeField2(char* mm, int length)
                {
                    TypeField selectName = null;
                    charNameOfField2.TryGetValue(length, out selectName);
                    return selectName;
                }

                public unsafe TypeField GetTypeField(char* mm, int length)
                {
                    SelectName selectName;
                    if (charNameOfField.TryGetValue(length, out selectName))
                    {
                        if (selectName.typeField == null)
                        {
                            long* lp = (long*)mm;
                            for (int i = 0; i < length / 4; i++)
                            {
                                long l = *lp;
                                if (selectName.select.TryGetValue(l, out selectName))
                                {
                                    return selectName.typeField;
                                }
                                ++lp;
                            }

                            long over = 0;
                            for (int i = length / 4 * 4; i < length; i++)
                            {
                                over |= ((long)(*(mm + i))) << (i * 2);
                            }

                            if (over != 0 && selectName.select.TryGetValue(over, out selectName))
                            {
                                return selectName.typeField;
                            }
                            return null;
                        }
                        else
                        {
                            return selectName.typeField;
                        }
                    }
                    else
                    {
                        return null;
                    }
                }

                Dictionary<int, SelectName> charNameOfField = new Dictionary<int, SelectName>();

                class SelectName
                {
                    public Dictionary<long, SelectName> select;
                    public TypeField typeField;
                    public long value;
                    public SelectName(TypeField typeField, long value)
                    {
                        this.typeField = typeField;
                        this.value = value;
                    }
                    public SelectName(long value)
                    {
                        this.select = new Dictionary<long, SelectName>();
                        this.value = value;
                    }
                    //public void Add(TypeField typeField, long l)
                    //{
                    //    if (typeField == null)
                    //    {

                    //    }
                    //    else
                    //    {
                    //        select = new Dictionary<long, SelectName>();
                    //        select[value] = typeField;
                    //        typeField = null;
                    //    }
                    //}
                }

            }



            public class TypeField
            {
                public TypeField(FieldInfo fieldInfo)
                {
                    this.fieldInfo = fieldInfo;
                    this.fieldType = fieldInfo.FieldType;
                    var handle = fieldInfo.FieldHandle;
                    //offset = UnsafeOperation.GetFeildOffset(handle.Value);
                    typeCode = Type.GetTypeCode(fieldType);
                    isValueType = fieldType.IsValueType;
                    isArray = fieldType.IsArray;
                    isEnum = fieldType.IsEnum;
                }

                /// <summary>
                ///  class struct
                /// </summary>
                public bool isValueType = false;

                public bool isArray = false;
                public bool isEnum = false;

                public FieldInfo fieldInfo;

                public Type fieldType;
                public int offset;
                public TypeCode typeCode;
                public TypeReflectionWarp warp;
            }
        }

        //static unsafe void Foo1(string[] args)
        //{

        //}

        //static unsafe void Foo1(ref string args)
        //{

        //}

        public void Foo1(string args)
        {
            args = null;
        }
        public void Foo1(int args)
        {

        }
        public static void Foo1(object args)
        {

        }

        public static void Foo2(object args)
        {

        }
        public static void Foo3(object args)
        {

        }

        public unsafe struct Chake
        {
            public int chakeIndex;
            public char chakeValue;
            public Chake* next;
            public Chake* no;
            public char* data;
            public char* noData;
            public int dataIndex;
            public int noDataIndex;
        }

        public unsafe class ChakeTree
        {
            public List<ChakeTree> chakeTrees = new List<ChakeTree>();
            public char chake;
            public int index = -1;
            public string[] strs;
            public void Fl() {

                Dictionary<char, int> dict = new Dictionary<char, int>();
                Dictionary<char, List<string>> dictList = new Dictionary<char, List<string>>();
                int nowIndex = index;
                int max = 0;
                char maxchar = ' ';
                do
                {
                    ++nowIndex;
                    dict = new Dictionary<char, int>();
                    dictList = new Dictionary<char, List<string>>();
                    for (int i = 0; i < strs.Length; i++)
                    {
                        char now = strs[i][nowIndex];
                        if (dict.ContainsKey(now))
                        {
                            ++dict[now];
                            dictList[now].Add(strs[i]);
                        }
                        else
                        {
                            dict[now] = 1;
                            dictList[now] = new List<string>();
                            dictList[now].Add(strs[i]);
                        }
                        if (dict[now] > max)
                        {
                            max = dict[now];
                            maxchar = now;
                        }
                    }
                    dict = dict.OrderByDescending(x => x.Value).ToDictionary(x => x.Key, x => x.Value);
                } while (dict.Count == 1);
                //chake = dict.First().Key;
                foreach (var item in dict)
                {
                    ChakeTree chakeTree = new ChakeTree();
                    chakeTree.chake = item.Key;
                    chakeTree.index = nowIndex;
                    chakeTree.strs = dictList[chakeTree.chake].ToArray();
                    chakeTrees.Add(chakeTree);
                    if (chakeTree.strs.Length > 1)
                    {
                        chakeTree.Fl();
                    }
                }
            }

            public void Over(char* allChar,int size, Chake* chakes, int id) 
            {
                for (int i = 0; i < chakeTrees.Count - 1; i++)
                {
                    chakes[id].chakeIndex = chakeTrees[i].index;
                    chakes[id].chakeValue = chakeTrees[i].chake;
                    chakes[id].data = allChar + size * id;
                    chakes[id].dataIndex = id;
                    chakes[id].no = chakes + (chakeTrees[i].strs.Length);
                    if (chakeTrees[i].chakeTrees.Count > 0)
                    {
                        chakes[id].next = chakes + (id + i);
                        chakeTrees[i].Over(allChar, size, chakes, id + i);
                        //for (int j = 0; j < chakeTrees[i].chakeTrees.Count; j++)
                        //{
                        //    chakes[id].next = chakes + (id + j);
                        //    chakeTrees[i].chakeTrees[j].Over(allChar, size, chakes, id + j);
                        //}
                    }
                }
                int overI = chakeTrees.Count - 2;
                chakes[id].noData = allChar + size * 2;
                chakes[id].noDataIndex = 2;


            }



        }

        static unsafe void Main(string[] args)
        {
            //string nnnn = typeof(Chake).Assembly.GetName().Name;
            string nnnn = typeof(List<int>).ToString();
            
            StreamReader streamReader = new StreamReader(@"TextFile1.json", Encoding.UTF8);
            string str = streamReader.ReadToEnd();

            JsonRender jsonRender = new JsonRender();
            CollectionManager.Start();
            int poo = jsonRender.ReadJsonText(str);
            object o = jsonRender.CreateObject(typeof(A), str);


            Console.ReadKey();
            //System.Collections.CollectionBase

            string[] strs = new string[]
            {
                "a",
                "b",
                "c",
                "d",
                "e",
                "f",
                "g",
                "h",
                "i",
                "j",
                "k",
                "l",
                "m",
                "n",
                "o",
                "p",
                "q",
                "r",
                "s",
                "t",
                "u",
                "v",
                "w",
                "x",
                "y",
                "z",
            };

            strs = (from p in typeof(A).GetFields()
                    select p.Name).ToArray();


            Dictionary<string, int> stringToIndex = new Dictionary<string, int>();
            for (int i = 0; i < strs.Length; i++)
            {
                stringToIndex[strs[i]] = i;
            }
            CharPointerTable.StringTable stringTable = new CharPointerTable.StringTable(stringToIndex);
            string cccc = "eqewq";
            int cccclength = cccc.Length;
            int[] chake = new int[strs.Length];
            for (int i = 0; i < strs.Length; i++)
            {
                cccc = strs[i];
                fixed (char* str2 = cccc)
                {
                    chake[i] = stringTable.Find(str2, cccc.Length);
                }
            }
            Stopwatch oTime = new Stopwatch();

            oTime.Reset(); oTime.Start();
            for (int __1 = 0; __1 < testCount; __1++)
            {
                for (int i = 0; i < strs.Length; i++)
                {
                    cccc = strs[i];
                    fixed (char* str2 = cccc)
                    {
                        chake[i] = stringTable.Find(str2, cccc.Length);
                    }
                }
            }
            oTime.Stop();
            Console.WriteLine("1：{0} 毫秒", oTime.Elapsed.TotalMilliseconds);

            oTime.Reset(); oTime.Start();
            for (int __1 = 0; __1 < testCount; __1++)
            {
                for (int i = 0; i < strs.Length; i++)
                {
                    cccc = strs[i];
                    fixed (char* str2 = cccc)
                    {
                        chake[i] = stringToIndex[new string(str2, 0, cccc.Length)];
                    }
                }
            }
            oTime.Stop();
            Console.WriteLine("2：{0} 毫秒", oTime.Elapsed.TotalMilliseconds);



            //ChakeTree chakeTree = new ChakeTree();
            //chakeTree.strs = strs;
            //chakeTree.Fl();

            //int size = "AAABBBCCC".Length + 1;
            //var stackIntPtr = Marshal.AllocHGlobal(strs.Length * Marshal.SizeOf(typeof(Chake)));
            //Chake* chakes = (Chake*)stackIntPtr.ToPointer();

            //stackIntPtr = Marshal.AllocHGlobal(strs.Length * size * Marshal.SizeOf(typeof(char)));
            //char* allChar = (char*)stackIntPtr.ToPointer();
            ////string all = "AAABBBCCC" + "\0" + "AAAEEECCC" + "\0" + "AAAEEEDDD" + "\0" + "UUEEEDDDD" + "\0" + "UUCCCRRRR" + "\0";
            //for (int i = 0; i < strs.Length; i++)
            //{
            //    for (int j = 0; j < size - 1; j++)
            //    {
            //        *(allChar + i * strs.Length + j) = strs[i][j];
            //    }
            //    *(allChar + i * strs.Length + size) = '\0';
            //}
            //chakeTree.Over(allChar, size, chakes, 0);


            Console.ReadKey();


            /*
           //MulticastDelegate
            Type type1 = Type.GetType( "System.Int32");
            Type type2 = Type.GetType("DogJson.Program");

            Action<object> action = Foo1;
            action += Foo2;
            action += Foo3;

            Type type_action = action.GetType();
            var type_action2 = type_action.IsSubclassOf(typeof(Delegate));
            TypeCode typeCode = Type.GetTypeCode(type_action);


            MulticastDelegate multicast = action;
            var ds = action.GetMethodInfo(); 
            var invocationList = action.GetInvocationList(); 

            ParameterModifier parameterModifier = new ParameterModifier(1);
            parameterModifier[0] = false;

            MethodInfo methodInfo = typeof(Program).GetMethod("Foo1",
                BindingFlags.NonPublic | BindingFlags.Instance
                | BindingFlags.Public | BindingFlags.Static,
                null,
                new Type[] { typeof(string) },
               null
             );


            //Console.WriteLine(methodInfo);


            //MethodInfo methodInfo = typeof(Program).GetMethod("Foo1", BindingFlags.NonPublic | BindingFlags.Instance
            //    | BindingFlags.Public | BindingFlags.Static);


            //var parameters = methodInfo.ReturnParameter;      
            ////Void Main(System.String[])

            Console.WriteLine(ds);//Void Main(System.String[])
            //LinkedList<int> ts = new LinkedList<int>();
            //ts.AddLast
            Console.ReadKey();

           B[]  bs = new B[10];
           bs[0].num = 133.5555; 
            bs[0].str = "qeqdasd";
            bs[1].str = "55555";
           bs[1].num = 133.5555;
           //Test001class.Run();
           IntPtr intPtr = MeasureArrayAdjustment<B>();
           Pinnable<B> _pinnable = Unsafe.As<Pinnable<B>>(bs);
           B v1143234 =  GetPinnableReference<B>(_pinnable, new IntPtr(intPtr.ToInt32()  ));
           Console.WriteLine(v1143234.str);
           //Console.WriteLine(((char)96));//49
           //Test001class.Run();

           str = str.Replace("\t", "");
           //ReadJsonData readJsonData = new ReadJsonData(); 
            Stopwatch oTime = new Stopwatch();

           fixed (char* ptr = str)
           {
               oTime.Reset(); oTime.Start();
               for (int i = 0; i < 1000000; i++)
               {
                   SpanString spanString = new SpanString(ptr, 10,9);
               }
               oTime.Stop();
               Console.WriteLine("spanString ：{0} 毫秒", oTime.Elapsed.TotalMilliseconds);

               oTime.Reset(); oTime.Start();
               for (int i = 0; i < 1000000; i++)
               {
                   string sstring = new string(ptr, 10, 9);
               }
               oTime.Stop();
               Console.WriteLine(" string：{0} 毫秒", oTime.Elapsed.TotalMilliseconds);

               oTime.Reset(); oTime.Start();
               for (int i = 0; i < 1000000; i++)
               {
                   string sstring = new string(ptr, 10, 9);
               }
               oTime.Stop();
               Console.WriteLine(" string：{0} 毫秒", oTime.Elapsed.TotalMilliseconds);
           }

        //   */



            //oTime.Reset(); oTime.Start();
            //for (int i = 0; i < testCount; i++)
            //{
            //    jsonRender.ReadJsonText(str);
            //}
            //oTime.Stop();

            //Console.WriteLine("ReadJsonText：{0} 毫秒", oTime.Elapsed.TotalMilliseconds);

            //A obj;
            //oTime.Reset(); oTime.Start();
            //for (int i = 0; i < testCount; i++)
            //{
            //    //obj = (A)jsonRender.ToObject(typeof(A), str);
            //}
            //oTime.Stop();
            //Console.WriteLine("ToObject：{0} 毫秒", oTime.Elapsed.TotalMilliseconds);
            Console.ReadKey();
        }

        public struct P3
        {
            public float x;
            public float y;
            public float z;
        }

        [Collection(typeof(Program.P3), false)]
        public unsafe class CollectionP3 : CollectionObjectBase<Program.P3, CollectionP3.V3_>
        {
            public override unsafe Type GetItemType(char* key, int keyLength)
            {
                return typeof(float);
            }

            protected override unsafe void Add(V3_ obj, char* key, int keyLength, object value)
            {
            }

            protected override unsafe void AddValue(V3_ obj, char* key, int keyLength, char* str, JsonValue* value)
            {
                switch (value->type)
                {
                    case JsonValueType.Long:
                        switch (*key)
                        {
                            case 'x':
                                obj.v3.x = (float)value->valueLong;
                                break;
                            case 'y':
                                obj.v3.y = (float)value->valueLong;
                                break;
                            case 'z':
                                obj.v3.z = (float)value->valueLong;
                                break;
                        }
                        break;
                    case JsonValueType.Double:
                        switch (*key)
                        {
                            case 'x':
                                obj.v3.x = (float)value->valueDouble;
                                break;
                            case 'y':
                                obj.v3.y = (float)value->valueDouble;
                                break;
                            case 'z':
                                obj.v3.z = (float)value->valueDouble;
                                break;
                        }
                        break;
                }
            }

            protected override CollectionP3.V3_ CreateObject(Type objectType, Type parentType)
            {
                return new V3_();
            }

            protected override P3 End(V3_ obj)
            {
                return obj.v3;
            }

            public class V3_
            {
                public Program.P3 v3;
            }
          
        }


        [Collection(typeof(Program.V3), true)]
        public unsafe class CollectionArrayV3 : CollectionArrayBase<Program.V3, CollectionArrayV3.V3_>
        {
            public class V3_
            {
                public Program.V3 v3;
            }
            protected override void AddValue(V3_ obj, int index, char* str, JsonValue* value)
            {
                switch (value->type)
                {
                    case JsonValueType.Long:
                        switch (index)
                        {
                            case 0:
                                obj.v3.x = (float)value->valueLong;
                                break;
                            case 1:
                                obj.v3.y = (float)value->valueLong;
                                break;
                            case 2:
                                obj.v3.z = (float)value->valueLong;
                                break;
                        }
                        break;
                    case JsonValueType.Double:
                        switch (index)
                        {
                            case 0:
                                obj.v3.x = (float)value->valueDouble;
                                break;
                            case 1:
                                obj.v3.y = (float)value->valueDouble;
                                break;
                            case 2:
                                obj.v3.z = (float)value->valueDouble;
                                break;
                        }
                        break;
                }
            }
            protected override V3_ CreateArray(int arrayCount, Type arrayType, Type parentType)
            {
                return new V3_();
            }
            protected override V3 End(V3_ obj)
            {
                return obj.v3;
            }
            public override Type GetItemType(int index)
            {
                return typeof(float);
            }

            protected override void Add(V3_ obj, int index, object value)
            {
                throw new NotImplementedException();
            }
        }

        public class TClass001 {
            public object[] objects;
            public double TestDuble;
            public TClass002 tClass002;
            public TClass002[] tClass002s;
        }
        public class TClass002
        {
            public double size;
            public string testString;
            public TClass003 tClass003;
            public TClass003[] tClass003s;
        }
        public class TClass003
        {
            public string testString;
        }

        public class TclassDCC
        {
            public TclassDCC(string str, IList<int> array, double num) {
                this.str = str;
                this.array = array;
                this.num = num;
            }
            public string str;
            public IList<int> array;
            public double num;
        }

        public class A
        {
            public TclassDCC dcc;
            
            public object ddd;
            public object[] objects;
            public TClass001 tClass001;
            public TClass003 testClassDD;
            public TClass003 testClassDD2;
            public TClass003 testClassDD3;
            public TClass003 testClassDD4;


            public IList<int> arraybool2;
            public TclassA Iclass0Z;
            public P3 p3;
            public int[,,] arrayArray1;
            public int[,][] arrayArray2;
            public int[] arrayArray3;
            public int[][] arrayArray4;
            public B[,,] arrayRekn;
            public Action<int, string> testDelegate2;
            public bool b;
            public double num;
            public int kk;
            public string str;
            public Stack<int> arrayint;
            public B[] fd;
            public C gcc;
            public HashSet<double> arraydouble;
            public Queue<string> arraystring;
            public List<bool> arraybool;
            public LinkedList<long> arrayLinkedList;
            public Dictionary<int, string> dictionary1;
            public Dictionary<int, B> dictionary2;
            public Dictionary<V3, B> dictionary3;
            public V3 v3;
        }

        public class TclassA
        {
            public bool b;
        }
        public class TclassC : TclassA
        {
            public double value;
            public B bbb;
        }


        public struct B
        {
            public bool b;
            public double num;
            public string str;
        }

        public struct C
        {
            public double k;
            public B bbb;
        }
        public struct V3
        {
            public float x;
            public float y;
            public float z;
        }



        [StructLayout(LayoutKind.Explicit)]
        struct D
        {
            [FieldOffset(0)]
            public bool b;

            [FieldOffset(1)]
            public double k;

            [FieldOffset(16)]
            public string str;

            [FieldOffset(40)]
            public E e;
        }


        class E
        {
            public bool b;
            public double k;
            public string str;
        }

    }
}
